package com.raycloud.dingtalk.starter.context;


import com.raycloud.dingtalk.starter.annotation.Command;
import com.raycloud.dingtalk.starter.annotation.RayOption;
import com.raycloud.dingtalk.starter.handle.CommandHandle;
import org.apache.commons.cli.Options;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author fay  fay9395@gmail.com
 * @date 2019-07-22 11:40.
 */
public class CommandContext {
    private static ConcurrentHashMap<String, CommandHandle> commandHandleMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, Command> commandMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, RayOption[]> commandOptionMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, Options> optionsCache = new ConcurrentHashMap<>();

    public static void register(String name, Command command, CommandHandle commandHandle, RayOption[] rayOptions) {
        commandMap.put(name, command);
        commandHandleMap.put(name, commandHandle);
        commandOptionMap.put(name, rayOptions);
    }

    public static CommandHandle of(String name) {
        if (!commandHandleMap.containsKey(name)) {
            throw new IllegalArgumentException("找不到对应的命令");
        }
        return commandHandleMap.get(name);
    }

    public static RayOption[] getOptions(String name) {
        if (!commandHandleMap.containsKey(name)) {
            throw new IllegalArgumentException("找不到对应的命令");
        }
        return commandOptionMap.get(name);
    }

    public static Options buildOptions(String name) {
        if (!commandHandleMap.containsKey(name)) {
            throw new IllegalArgumentException("找不到对应的命令");
        }
        Options options = optionsCache.get(name);
        if (options != null) {
            return options;
        }
        optionsCache.put(name, options = new Options());
        StringBuilder help = new StringBuilder();
        for (RayOption rayOption : getOptions(name)) {
            options.addOption(rayOption.opt(), rayOption.longOpt(), rayOption.hasArg(), rayOption.description());
            help.append("-").append(rayOption.opt()).append(", ").append("-").append(rayOption.longOpt()).append(":\t").append(rayOption.description()).append("\n");
        }
        help.append("-").append("h").append(", ").append("-").append("help").append(":\t").append("使用帮助");
        options.addOption("h", "help", false, help.toString());
        return options;
    }

    public static String buildCommandHelp() {
        StringBuilder help = new StringBuilder();
        for (Map.Entry<String, Command> entry : commandMap.entrySet()) {
            help.append(entry.getKey()).append(":").append("\t").append(entry.getValue().description()).append(", 具体请看:").append(entry.getKey()).append(" -h").append("\n");
        }
        help.deleteCharAt(help.length() - 1);
        return help.toString();
    }

    public static boolean support(String name) {
        return commandMap.containsKey(name);
    }
}
